package controls
{
  import flash.events.Event;
  import flash.events.FocusEvent;
  import flash.events.KeyboardEvent;
  import flash.ui.Keyboard;
  import mx.binding.utils.BindingUtils;
  import mx.collections.IList;
  import mx.core.IFactory;
  import mx.events.FlexEvent;
  import spark.components.DropDownList;
  import spark.components.Group;
  import spark.events.DropDownEvent;
  import spark.events.IndexChangeEvent

  [Event("enter", type="mx.events.FlexEvent")]

  /**
   * ...
   * @author Roman Marchenko
   */
  public class SimpleComboBox extends Group
  {
    private var _dropDownList:DropDownList;
    private var _textInputSimple:TextInputSimple;

    public function SimpleComboBox()
    {
      super();
      _dropDownList = new DropDownList;
      _textInputSimple = new TextInputSimple;
    }

    /**
     *  @private
     */
    override protected function createChildren():void
    {
      super.createChildren();

      // Dropdown list
      _dropDownList.addEventListener(spark.events.DropDownEvent.CLOSE, dropDownList_closeHandler);
      _dropDownList.addEventListener(spark.events.IndexChangeEvent.CHANGE, dropDownList_changeHandler);
      addElement(_dropDownList);
      _dropDownList.move(0, 0);
      _dropDownList.percentWidth = 100;
      _dropDownList.percentHeight = 100;

      // Text input
      _textInputSimple.editable = true;
      _textInputSimple.restrict = "^\u001b";
      _textInputSimple.focusEnabled = false; // Don't show ESC characters in the text field.
      //_textInputSimple.imeMode = textInput.imeMode;
      //_textInputSimple.styleName = textInput.styleName;
      _textInputSimple.addEventListener(Event.CHANGE, textInputSimple_changeHandler);
      _textInputSimple.addEventListener(FlexEvent.ENTER, textInputSimple_enterHandler);
      _textInputSimple.addEventListener(FocusEvent.FOCUS_IN, focusInHandler);
      _textInputSimple.addEventListener(FocusEvent.FOCUS_OUT, focusOutHandler);
      _textInputSimple.addEventListener(KeyboardEvent.KEY_DOWN, textInputSimple_keyDownHandler);
      addElement(_textInputSimple);
      _textInputSimple.move(0, 0);

      BindingUtils.bindProperty(_textInputSimple, "height", _dropDownList, "height");
      BindingUtils.bindProperty(_textInputSimple, "width", _dropDownList, "width");

      //_textInputSimple.parentDrawsFocus = true;

      //textInput.visible = false;
      //textInput.includeInLayout = false;
      //textInput.enabled = false;
      //textInput.width = 0;
      //textInput.height = 0;
    }

    /**
     *  Handles changes to the TextInput that serves as the editable
     *  text field in the component.
     *
     *  @param event The event that is triggered each time the text in the control changes.
     */
    protected function textInputSimple_changeHandler(event:Event):void
    {
      // Dispatch an event that the TextInput has been changed.
      //textInput.text = _textInputSimple.text;
      dispatchEvent(new Event("change"));
    }

    protected function textInputSimple_enterHandler(event:Event):void
    {
      if (_dropDownList.isDropDownOpen)
      {
        var s:String = String(_dropDownList.selectedItem.artist);
        text = s;

        // Enter was pressed to choose an iten in the dropdown list.
        // Don't dispatch this event.
        event.stopPropagation();
        return;
      }

      dispatchEvent(event);
    }

    protected function textInputSimple_keyDownHandler(e:KeyboardEvent):void
    {
      if (Keyboard.DOWN == e.keyCode && _dropDownList.isDropDownOpen)
      {
        // On 'DOWN' key go to the first element of the drop down list.
        _dropDownList.setFocus();
        _dropDownList.dispatchEvent(e);
      }

      dispatchEvent(e);
    }

    protected function dropDownList_changeHandler(event:Event):void
    {
      var s:String = String(_dropDownList.selectedItem.artist);
      text = s;
    }

    protected function dropDownList_closeHandler(event:Event):void
    {
      _textInputSimple.setFocus();
      var s:String = String(_textInputSimple.text);
      _textInputSimple.selectRange(s.length, s.length);
    }

    override public function setFocus():void
    {
      _textInputSimple.setFocus();
    }

    public function closeDropDown(commit:Boolean):void
    {
      _dropDownList.closeDropDown(commit);
    }

    public function openDropDown():void
    {
      _dropDownList.openDropDown();
    }

    //----------------------------------
    //  textSimple
    //----------------------------------

    //[Inspectable(category="General",defaultValue="")]
    //[NonCommittingChangeEvent("change")]

    [Bindable(event="change")]

    /**
     *  @private
     */
    public function set text(value:String):void
    {
      _textInputSimple.text = value;
      //invalidateProperties();
      dispatchEvent(new Event("change"));
    }

    /**
     *  Contents of the text field.
     *
     *  @default ""
     */
    public function get text():String
    {
      return _textInputSimple.text;
    }

    //----------------------------------
    //  itemRenderer
    //----------------------------------

    public function set itemRenderer(value:IFactory):void
    {
      _dropDownList.itemRenderer = value;
    }

    public function get itemRenderer():IFactory
    {
      return _dropDownList.itemRenderer;
    }

    //----------------------------------
    //  dataProvider
    //----------------------------------

    public function set dataProvider(value:IList):void
    {
      _dropDownList.dataProvider = value;
    }

    public function get dataProvider():IList
    {
      return _dropDownList.dataProvider;
    }

    //----------------------------------
    //  labelField
    //----------------------------------

    //[Bindable(event="change")]

    public function set labelField(value:String):void
    {
      _dropDownList.labelField = value;
    }

    public function get labelField():String
    {
      return _dropDownList.labelField;
    }

    //----------------------------------
    //  selectedItem
    //----------------------------------

    public function set selectedItem(value:*):void
    {
      _dropDownList.selectedItem = value;
    }

    public function get selectedItem():*
    {
      return _dropDownList.selectedItem;
    }

    //----------------------------------
    //  selectedIndex
    //----------------------------------

    public function set selectedIndex(value:int):void
    {
      _dropDownList.selectedIndex = value
    }

    public function get selectedIndex():int
    {
      return _dropDownList.selectedIndex;
    }
  }

}